<?php

class TimeTracker
{

	/**
	 * 
	 * Calculates difference between two dates (any format will be accepted).
	 * If a $units array is specified it will return the difference partiotioned in that units, 
	 * otherwise it will patiotion the difference as array with the following  keys: 
	 * 
	 * years, months, weeks, days, hours, minutes, seconds
	 * 
	 * If the 'to' date is not specified, now will be assumed as default.  
	 * 
	 * 
	 * It is intended for times that are very close together. 
	 * It will not be accurate for calculating dates more than a month apart. 
	 * This is because one of the units it relies on is "weeks," which do not correspond directly with months. 
	 * What I'm trying to get across is, the program assumes that a month is precisely 4 weeks long, i.e. 28 days. 
	 * This also means that a "year" according to this function is 336 days.
	 * 
	 * @param $from
	 * @param $to 
	 * @param $unitFields
	 * 
	 * @return Array
	 */
	public static function calculateDateDifference($from, $to = null, $unitFields = null){

		//TODO: find a better method to calculate differnces 
		 
		$to = (($to === null) ? (time()) : ($to));
		$to = ((is_int($to)) ? ($to) : (strtotime($to)));
		$from = ((is_int($from)) ? ($from) : (strtotime($from)));

		$units = self::getUnits($unitFields); 
		
		$rawDifference = abs($from - $to);
		$difference = array(); 
		
		foreach($units as $unit => $multplier){
			
			if($rawDifference >= $multplier)
			{
				$value = intval($rawDifference / $multplier); 
				$difference[$unit] = $value;  
				$rawDifference -= $value * $multplier;
			}
			
		}

		return $difference;

	}
	
	private static function getUnits($unitFields = null){
		
		$allUnits = array (
		   "years"   => 29030400, // seconds in a year   (12 months)
		   "months"  => 2419200,  // seconds in a month  (4 weeks)
		   "weeks"   => 604800,   // seconds in a week   (7 days)
		   "days"    => 86400,    // seconds in a day    (24 hours)
		   "hours"   => 3600,     // seconds in an hour  (60 minutes)
		   "minutes" => 60,       // seconds in a minute (60 seconds)
		   "seconds" => 1         // 1 second
		);
		
		if($unitFields){
			$units = array(); 
			
			foreach ($unitFields as $field) {
				$units[$field] = $allUnits[$field]; 
			}
		} 
		
		return $unitFields ? $units : $allUnits; 
	}

}